let fs = require('fs')
let path = require('path')
let Mock = require('mockjs')
let Axios = require('axios')
var cookieParser = require('cookie-parser');

const css = `
<style>
  pre {outline: 1px solid #ccc padding: 5px margin: 5px }
  .string { color: green }
  .number { color: darkorange }
  .boolean { color: blue }
  .null { color: magenta }
  .key { color: red }
</style>
`

RegExp.prototype.toJSON = RegExp.prototype.toString

let pickMockType = (json, type) => {
  let mock = Mock.mock(json)

  if (null != type) {
    if (mock.hasOwnProperty('data.' + type)) {
      mock['data'] = mock['data.' + type]
    }

    let other = []
    Object.keys(mock).forEach(k => {
      if (k.startsWith('data.')) {
        other.push(k)
      }
    })

    for (let k in other) {
      delete mock[other[k]]
    }
  }

  return mock
}

let mockJson = (json, type = null, tab2space = 2) =>
    JSON.stringify(pickMockType(json, type), null, tab2space)

let mockJsonHtml = (json, type = null, tab2space = 2) =>
    beautifyJson(pickMockType(json, type), tab2space)

let beautifyJson = (json, tab2space = 2) =>
css + '<pre>' + json2html(json, tab2space) + '</pre>'

let setupExpressLog = (app, stdout, file) => {
  let morgan = require('morgan')

  if (stdout) {
    app.use(morgan('dev'))
  }

  if (file) {
    let accessLog = fs.createWriteStream(path.join(__dirname, "..", file),
        {flags: 'a'})
    app.use(morgan('short', {stream: accessLog}))
  }
}

let read = (file, enc) => {
  enc = enc || 'utf8'
  return fs.readFileSync(file, enc)
}

let jsonTodo = (json, todo) => {
  for (let j in json) {
    if ('object' == typeof json[j]) {
      jsonTodo(json[j], todo)
    } else {
      todo(json, j)
    }
  }
}

let reg = (json, key) => {
  if ('string' == typeof json[key]) {
    let text = json[key]
    if (text.startsWith('/') && text.endsWith('/')) {
      json[key] = new RegExp(text.replace(/\//g, ''))
    }
  }
}

let regJson = json => jsonTodo(json, reg)

let ls = function (path, list, recursive) {
  recursive = recursive || true

  if (fs.statSync(path).isFile()) {
    if (path.endsWith(".json")) {
      list.push(path)
    }
    return list
  }

  let thiz = this

  try {
    fs.readdirSync(path).forEach(function (file) {
      if (recursive) {
        ls.call(thiz, path + "/" + file, list)
      } else {
        list.push(path + "/" + file)
      }
    })
  } catch (e) {
    console.log(e)
  }

  return list
}

let json2html = (json, tab2space = 2) => {
  if (typeof json != 'string') {
    json = JSON.stringify(json, null, tab2space)
  }

  json = json.replace(/&/g, '&')
      .replace(/</g, '<')
      .replace(/>/g, '>')

  return json.replace(
      /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
      function (match) {
        let cls = 'number'
        if (/^"/.test(match)) {
          if (/:$/.test(match)) {
            cls = 'key'
          } else {
            cls = 'string'
          }
        } else if (/true|false/.test(match)) {
          cls = 'boolean'
        } else if (/null/.test(match)) {
          cls = 'null'
        }
        return '<span class="' + cls + '">' + match + '</span>'
      })
}

let axios = (base, api, dataArr, method = 'POST', number = 1) => {
  let list = []
  for (var i = 0; i < number; i++) {
    var data = dataArr[i] || {}
    let pro = new Promise((resolve, reject) => {
      Axios({
        method: method,
        baseURL: base,
        url: api,
        params: method == 'POST' ? null : data,
        data: data,
        responseType: 'json',
        withCredentials: true,
      })
          .then(function (response) {
            resolve(response)
          })
          .catch(function (error) {
            reject(error)
          })

    })
    list.push(pro);
  }
  return Promise.all(list)
}

module.exports.mockJson = mockJson
module.exports.mockJsonHtml = mockJsonHtml
module.exports.setupExpressLog = setupExpressLog
module.exports.read = read
module.exports.axios = axios

module.exports.ls = ls
module.exports.regJson = regJson
module.exports.beautifyJson = beautifyJson

